package org.atlantis.grosbeak.depot.proxy;

import org.atlantis.grosbeak.depot.DepotMaker;
import org.atlantis.grosbeak.depot.EventTrigger;
import org.atlantis.grosbeak.depot.ObjectWeaver;

/**
 * 容器中所有对象的代理对象。此代理包括：对象的构造方式和对象的事件（准确来说是obtain事件）。
 * 
 * @author <a href="mailto:seenoevil.cn@gmail.com">SeeNoEvil</a>
 * 
 */
@SuppressWarnings("unchecked")
public class ObjectProxy {

	private ObjectWeaver weaver;

	private EventTrigger<Object> obtain;

	/**
	 * 设定对象的构建方式。
	 * 
	 * @param weaver
	 *            对象的构建方式。
	 * @return 代理对象。
	 */
	public ObjectProxy setWeaver(ObjectWeaver weaver) {
		this.weaver = weaver;
		return this;
	}

	/**
	 * 设定对象的obtain事件。因为真正从容器中获取对象就是调用ObjectProxy的get方法。
	 * 所以在ObjectProxy的get方法中会触发对象的obtain事件。
	 * 
	 * @param obtain
	 *            obtain事件。
	 * @return 代理对象。
	 */
	public ObjectProxy setObtain(EventTrigger<Object> obtain) {
		this.obtain = obtain;
		return this;
	}

	/**
	 * 从代理中获取一个真实的对象。
	 * 
	 * @param clazz
	 *            真实的对象的类型。
	 * @param maker
	 *            DepotMaker对象。
	 * @return 真实的对象。
	 */
	public <T> T get(Class<T> clazz, DepotMaker maker) {
		Object obj = weaver.weave(maker);
		if (null != obtain)
			obtain.trigger(obj);
		return (T) obj;
	}

	/**
	 * 销毁真实对象。
	 */
	public void destroy() {
		weaver.destroy();
	}
}
